package pl.wr.physics.units;

import pl.wr.math.Component;
import pl.wr.math.number.Fraction;
import pl.wr.physics.units.SI.Prefix;

/**
 * Abstract class of unit
 * 
 * @version 1.0
 * @author wieslaw.rodak
 * 
 */
public abstract class AbstractUnit implements Component {

	/**
	 * The value in this unit
	 */
    private final Fraction value;

	/**
	 * SI prefix of value
	 */
	private final Prefix prefix;

	/**
	 * String representation of unit
	 */
	private final String unit;

	/**
	 * second
	 * 
	 * @param p
	 *            - prefix SI
	 * @param value
	 *            - value in <code>int</code>
	 * @param unit
	 *            - string representation of unit
	 */
	protected AbstractUnit(Prefix p, int value, String unit) {
		this.value = new Fraction(value);
		prefix = p;
		this.unit = unit;
	}

	/**
	 * second
	 * 
	 * @param p
	 *            - prefix SI
	 * @param value
	 *            - value in <code>float</code>
	 * @param unit
	 *            - string representation of unit
	 */
	protected AbstractUnit(Prefix p, float value, String unit) {
		this.value = new Fraction(value);
		prefix = p;
		this.unit = unit;
	}

	/**
	 * second
	 * 
	 * @param p
	 *            - prefix SI
	 * @param value
	 *            - value in <code>Fraction</code>
	 * @param unit
	 *            - string representation of unit
	 */
	protected AbstractUnit(Prefix p, Fraction value, String unit) {
		this.value = value;
		prefix = p;
		this.unit = unit;
	}

	/**
	
	 * @return complex value in <code>Fraction</code> */
	public Fraction getValue() {
		return Fraction.multiply(value, prefix.getValue());
	}

	/**
	 * @param p
	 *            - prefix (SI) of output value
	
	 * @return complex value in <code>Fraction</code> */
	public Fraction getValue(Prefix p) {
		return Fraction.divide(getValue(), p.getValue());
	}

	/**
	 * @param p
	 *            - prefix (SI) of output value
	
	 * @return Returns a string representation of the object */
	public String toString(Prefix p) {
		final StringBuilder builder = new StringBuilder(32);
		builder.append(getValue(p).doubleValue());
		builder.append(' ');
		builder.append((p.toString().equals("basic")) ? "" : p); //$NON-NLS-1$
		builder.append(unit);
		return builder.toString();
	}

	/**
	 * Method toString.
	 * @return String
	 */
	@Override
	public String toString() {
		final StringBuilder builder = new StringBuilder(32);
		builder.append("[value="); //$NON-NLS-1$
		builder.append(value);
		builder.append(", prefix="); //$NON-NLS-1$
		builder.append(prefix);
		builder.append(", unit="); //$NON-NLS-1$
		builder.append(unit);
		builder.append(']');
		return builder.toString();
	}

}
